#pragma once
#ifndef STDMYLOG_H__
#define STDMYLOG_H__


#include <string>
#include <windows.h>
#include <tchar.h>
#include <list>
#include <string.h>

#include <Winsock2.h>
#include <mmsystem.h>
#include <process.h>

#include "Utility.h"

using namespace std;



class ThreadMng
{
public:
	ThreadMng();
	~ThreadMng();
	typedef void (*func)(void* parameter);
	void RegisterCallBk(func fnCallBack,void* parameter);
	void Start(int nInterval = 1000);
	void Stop();
	void RunThread();
private:
	int    m_nInterval;
	static UINT WINAPI ThreadProc(LPVOID pParam);
	func   m_fncallback;
	void*  m_fnparam;
	HANDLE m_hEvtEnd;
	HANDLE m_hThread;
	//DWORD m_uiThreadId;
};


#ifndef LOG_TRACE
#define LOG_TRACE   6
#define LOG_DEBUG_   5
#define LOG_INFO	 4    // EVENTLOG_INFORMATION_TYPE
#define LOG_WARNING_ 2 // EVENTLOG_WARNING_TYPE
#define LOG_ERROR	 1    // EVENTLOG_INFORMATION_TYPE
#endif

struct LogPackage
{
	SYSTEMTIME time;
	DWORD      m_nThreadID;
	int		   m_nlogType;
	
	char m_szModuleName[15];
	char m_szclass_memfunc[25];
	
	string m_szBuffer;
	
	LogConfig Info;
};
class CStdMyLog
{
public:
	CStdMyLog(void);
	virtual ~CStdMyLog(void);

	static CStdMyLog& GetInstance();
	static int m_bLogAsync;
private:
	CRITICAL_SECTION m_csMyBlock;
	static CStdMyLog _Instance;

	std::string GetTypeString(int LogType)const;

	static bool ShouldLog(const LogConfig& config, int nLog);
	static bool ShouldLogView(const LogConfig& config, int nLog);
private:
	inline void Lock_QueLog();
	inline void Unlock_QueLog();
	CRITICAL_SECTION m_csQueLog;
	list<LogPackage> m_queLog;
	bool m_bRuning;
	ThreadMng m_ThdMng;
	HANDLE m_hEvtQueNEmpty;
public:
	void DoLogHisLimit(const LogConfig& config)const;
	static void LogThread(void* param);
	void AddLog2Que(const LogConfig& config, LogPackage* pack);
	bool DelQueryLogQue(LogPackage* pack);
	void StartRunT();
	void StopRunT();
	void Run();

	static void SetUp(LogConfig& config, const char *szFilePath, int nLogLevl = 3, int nLogViewLevl = 3,bool bOutput = true, bool bOutputDebugView = true, bool bOutputFile = true, int LogHisLim = 24);
	void MyLogInfo(LogConfig& config, const char* modulename,const char* classname,const char* memfunc,int logType, SYSTEMTIME* time, const TCHAR* pzFormat, ...);
	void OutputLog(LogConfig& config, const char* classname,const char* memfunc,int logType, SYSTEMTIME* time, DWORD dwThreadID, const char* pszMsg);
	void OutputLog(LogConfig& config, int logType, const char* pszMsg);

	struct LogConfig* DefLogConfig();
};
inline void CStdMyLog::Lock_QueLog()
{
	EnterCriticalSection(&m_csQueLog);
}
inline void CStdMyLog::Unlock_QueLog()
{
	LeaveCriticalSection(&m_csQueLog);
}




#endif